package com.siqi.hr.system.custom.db.builder;

import com.siqi.hr.system.common.sql.RelatedTable;
import com.siqi.hr.system.common.sql.STable;
import com.siqi.hr.system.custom.db.builder.intf.DbCreater;
import com.siqi.hr.system.custom.entity.EntityRecord;
import org.apache.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 删除自定义实体记录，表，注册字段等相关信息
 * @author    xiaogq
 * @data      2016-08-30
 */
public class DbTableDeleter implements DbCreater {

    private static final Logger logger = Logger.getLogger(DbTableDeleter.class);

    //jdbcTemplate模板用于执行sql语句
    private JdbcTemplate jdbcTemplate = null;

    //主实体对象
    private EntityRecord entityRecord = null;

    /**
     * 根据主实体获取所有相关实体Id集合
     */
    private List<Integer> relatedIds = null;
    /**
     * 根据相关实体获取所有主实体Id集合
     */
    private List<Integer> beRelatedIds = null;

    //删除自定义实体时如果发生错误回滚操作sql
    private String rollbackSql = null;

    public DbTableDeleter(EntityRecord entityRecord) {
        this.entityRecord = entityRecord;
    }

    @Override
    public int create(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
        //查看创建实体表的sql语句
        pareparToDelete();
        //删除自定义实体想关注册表中的信息
        int lens = deleteRecord();
        if(lens > 0){
            //删除主实体一些相关注册表
            deleteTable();
        }
        return lens;
    }

    /**
     * 获取创建表sql语句
     */
    private void pareparToDelete() {
        //查看创建实体表的sql语句
        String sql = "show create table t_" + this.entityRecord.getTableCode();
        Map<String,Object> map = this.jdbcTemplate.queryForMap(sql);
        String tempSql = map.get("Create Table").toString();
        int i = tempSql.indexOf("CREATE TABLE") + "CREATE TABLE".length();
        this.rollbackSql = (" CREATE TABLE if not exists " + tempSql.substring(i));
        logger.debug("DbTableDeleter->" + this.rollbackSql);
    }

    /**
     * 删除自定义实体想关注册表中的信息
     */
    private int deleteRecord() {
        int [] lens = new int[0];
        //定义删除主实体及主实体下所有的明细实体记录
        List<String> suEntityIdList = new ArrayList<String>();
        //查询当前实体相关实体Id
        String sql = "select related_id from sys_related_config where host_id = ? ";
        this.relatedIds = this.jdbcTemplate.queryForList(sql,Integer.class, new Object[] {entityRecord.getTableCode()});
        //根据相关实体id查询主实体id
        String sql2 = "select host_id from sys_related_config where related_id = ?";
        this.beRelatedIds = this.jdbcTemplate.queryForList(sql2,Integer.class, new Object[] {entityRecord.getTableCode()});

        //删除实体注册表中实体记录信息
        StringBuffer entitySql = new StringBuffer("delete from sys_custom_entity where table_code = ").append(entityRecord.getTableCode());
        suEntityIdList.add(entitySql.toString());
        //删除字段注册表中该实体对应的字段信息
        StringBuffer fileSql = new StringBuffer("delete from sys_custom_field where entity_id = ").append(entityRecord.getTableCode());
        suEntityIdList.add(fileSql.toString());
        //删除菜单表中该实体对于的菜单记录
        StringBuffer menuSql = new StringBuffer("delete from sys_org_menu where entity_id = ").append(entityRecord.getTableCode());
        suEntityIdList.add(menuSql.toString());
        //删除该实体角色、操作关系表中记录
        StringBuffer operationSql = new StringBuffer("delete from sys_org_role_entity_operation where entity_id = ").append(entityRecord.getTableCode());
        suEntityIdList.add(operationSql.toString());
        if (suEntityIdList != null && suEntityIdList.size() > 0){
            lens = this.jdbcTemplate.batchUpdate(suEntityIdList.toArray(new String[suEntityIdList.size()]));
        }
        return lens.length;
    }

    /**
     * 删除主实体一些相关注册表
     */
    private void deleteTable() {
        List<String> sqlList = new ArrayList<String>();
        //取消外键约束
        String setforkeySql = " SET FOREIGN_KEY_CHECKS = 0 ";
        sqlList.add(setforkeySql);
        try {
            if (this.relatedIds != null) {
                String sqltn = null;
                for (Iterator<Integer> localIterator1 = this.relatedIds.iterator(); localIterator1.hasNext();) {
                    Integer id = localIterator1.next();
                    sqltn = " DROP TABLE IF EXISTS " + RelatedTable.RELATED_HEAD+entityRecord.getTableCode()+"_"+id;
                    sqlList.add(sqltn);
                }
            }
            if (this.beRelatedIds != null) {
                String sqln = null;
                for (Integer id : beRelatedIds) {
                    sqln = " DROP TABLE IF EXISTS " + RelatedTable.RELATED_HEAD+id+"_"+entityRecord.getTableCode();
                    sqlList.add(sqln);
                }
            }

            String deleteSql = " DROP TABLE IF EXISTS " + STable.TABLE_HEAD+ this.entityRecord.getTableCode();
            sqlList.add(deleteSql);
            if(sqlList != null && sqlList.size() > 0){
                jdbcTemplate.batchUpdate(sqlList.toArray(new String[sqlList.size()]));
            }
        } catch (DataAccessException e) {
            e.printStackTrace();
        } finally {
            jdbcTemplate.update(" SET FOREIGN_KEY_CHECKS = 1");
        }
    }

    @Override
    public void rollbackDbException() {
        if (this.rollbackSql != null)
            this.jdbcTemplate.update(this.rollbackSql);
    }
}
